raco dist: update ELF section when adjusting data size

Merge to v5.3.4
(cherry picked from commit f450e50354)
This commit is contained in:
Matthew Flatt 2013-04-24 18:42:54 -06:00 committed by Ryan Culpepper
parent bbb2bec62b
commit 2fea9c36fc
2 changed files with 67 additions and 16 deletions

View File

@ -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

View File

@ -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)))