From 2fea9c36fccc848a9d1e69e8985b5c68e12355ba Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 24 Apr 2013 18:42:54 -0600 Subject: [PATCH] raco dist: update ELF section when adjusting data size Merge to v5.3.4 (cherry picked from commit f450e50354fcf70a71d22621c958508b8f438766) --- collects/compiler/distribute.rkt | 37 +++++++++++++++---------- collects/compiler/private/elf.rkt | 46 ++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/collects/compiler/distribute.rkt b/collects/compiler/distribute.rkt index 699ca8ee36..18f23625c1 100644 --- a/collects/compiler/distribute.rkt +++ b/collects/compiler/distribute.rkt @@ -7,6 +7,7 @@ dynext/filename-version "private/macfw.rkt" "private/windlldir.rkt" + "private/elf.rkt" "private/collects-path.rkt") (provide assemble-distribution) @@ -305,7 +306,7 @@ (define (patch-stub-exe-paths b exe shared-lib-dir) ;; Adjust paths to executable and DLL that is embedded in the executable - (let-values ([(config-pos start end prog-len dll-len rest) + (let-values ([(config-pos all-start start end prog-len dll-len rest) (with-input-from-file b (lambda () (let* ([i (current-input-port)] @@ -314,7 +315,7 @@ (error 'patch-stub-exe-paths "cannot find config info")) (read-byte i) - (read-one-int i) ; start of decls + (define all-start (read-one-int i)) ; start of decls (read-one-int i) ; start of program (let ([start (read-one-int i)] ; start of data [end (read-one-int i)]) ; end of data @@ -322,6 +323,7 @@ (let ([prog-len (next-bytes-length i)] [dll-len (next-bytes-length i)]) (values (+ (cdar m) 1) ; position after "cOnFiG:[" tag + all-start start end prog-len @@ -335,19 +337,24 @@ (add1 (bytes-length exe-bytes)) (add1 (bytes-length shared-lib-bytes)))]) (with-output-to-file b - #:exists 'update - (lambda () - (let ([o (current-output-port)]) - (file-position o (+ config-pos 12)) ; update the end of the program data - (write-one-int (- end delta) o) - (flush-output o) - (file-position o start) - (write-bytes exe-bytes o) - (write-bytes #"\0" o) - (write-bytes shared-lib-bytes o) - (write-bytes #"\0" o) - (write-bytes rest o) - (flush-output o)))))))) + #:exists 'update + (lambda () + (let ([o (current-output-port)]) + (file-position o (+ config-pos 12)) ; update the end of the program data + (write-one-int (- end delta) o) + (flush-output o) + (file-position o start) + (write-bytes exe-bytes o) + (write-bytes #"\0" o) + (write-bytes shared-lib-bytes o) + (write-bytes #"\0" o) + (write-bytes rest o) + (flush-output o)))) + ;; May need to fix the size of the ELF section: + (adjust-racket-section-size + b + #rx#"^[.]rack(?:cmdl|prog)\0" + (- (- end all-start) delta)))))) (define (copy-and-patch-binaries copy? magic extract-src construct-dest transform-entry diff --git a/collects/compiler/private/elf.rkt b/collects/compiler/private/elf.rkt index 542fa1a8b1..4c3a04a0b1 100644 --- a/collects/compiler/private/elf.rkt +++ b/collects/compiler/private/elf.rkt @@ -1,6 +1,7 @@ #lang racket/base -(provide add-racket-section) +(provide add-racket-section + adjust-racket-section-size) (define 32BIT 1) (define 64BIT 2) @@ -314,3 +315,46 @@ (write-bytes data out) (values dest (+ dest (bytes-length data)) decl-len mid)))))))))))) + +(define (adjust-racket-section-size src-file name-regexp new-size) + (define fixup + (call-with-input-file* + src-file + (lambda (in) + (read-elf + in + (lambda () (values #f #f #f #f)) + (lambda (elf sections programs str-section strs) + (and elf + (for/or ([s (in-list sections)] + [i (in-naturals)]) + (and (regexp-match? name-regexp + strs + (min (section-name-offset s) + (bytes-length strs))) + (lambda (out) + (let ([class (elf-class elf)] + [format (elf-format elf)]) + (define-values (word-size xoff-size xword-size addr-size) + (if (= class 32BIT) + (values 4 4 4 4) + (values 4 8 8 8))) + ;; Go to section record, and specifically to + ;; the size field: + (file-position out (+ (elf-sh-offset elf) + (* i (elf-sh-esize elf)) + (* 2 word-size) + xword-size + addr-size + xoff-size)) + ;; Write the new size: + (display (integer->integer-bytes new-size + xword-size + #f + (= format BIGEND)) + out))))))))))) + (when fixup + (call-with-output-file* + src-file + #:exists 'update + fixup)))