write proper ELF section for Unix launchers/executables
This commit is contained in:
parent
875385b8f7
commit
6b2219b9e5
|
@ -15,6 +15,7 @@
|
|||
"private/winsubsys.ss"
|
||||
"private/macfw.ss"
|
||||
"private/mach-o.ss"
|
||||
"private/elf.ss"
|
||||
"private/windlldir.ss"
|
||||
"private/collects-path.ss"
|
||||
"find-exe.rkt")
|
||||
|
@ -1168,8 +1169,44 @@
|
|||
compiler
|
||||
expand-namespace
|
||||
src-filter
|
||||
get-extra-imports))])
|
||||
(let-values ([(start end)
|
||||
get-extra-imports))]
|
||||
[make-full-cmdline
|
||||
(lambda (start end)
|
||||
(let ([start-s (number->string start)]
|
||||
[end-s (number->string end)])
|
||||
(append (if launcher?
|
||||
(if (and (eq? 'windows (system-type))
|
||||
keep-exe?)
|
||||
;; argv[0] replacement:
|
||||
(list (path->string
|
||||
(if relative?
|
||||
(relativize exe dest-exe values)
|
||||
exe)))
|
||||
;; No argv[0]:
|
||||
null)
|
||||
(list "-k" start-s end-s))
|
||||
cmdline)))]
|
||||
[make-starter-cmdline
|
||||
(lambda (full-cmdline)
|
||||
(apply bytes-append
|
||||
(map (lambda (s)
|
||||
(bytes-append
|
||||
(cond
|
||||
[(path? s) (path->bytes s)]
|
||||
[else (string->bytes/locale s)])
|
||||
#"\0"))
|
||||
(append
|
||||
(list (if relative?
|
||||
(relativize exe dest-exe values)
|
||||
exe)
|
||||
(let ([dir (find-dll-dir)])
|
||||
(if dir
|
||||
(if relative?
|
||||
(relativize dir dest-exe values)
|
||||
dir)
|
||||
"")))
|
||||
full-cmdline))))])
|
||||
(let-values ([(start end cmdline-end)
|
||||
(if (and (eq? (system-type) 'macosx)
|
||||
(not unix-starter?))
|
||||
;; For Mach-O, we know how to add a proper segment
|
||||
|
@ -1178,29 +1215,37 @@
|
|||
(let ([s (get-output-bytes s)])
|
||||
(let ([start (add-plt-segment dest-exe s)])
|
||||
(values start
|
||||
(+ start (bytes-length s))))))
|
||||
;; Other platforms: just add to the end of the file:
|
||||
(let ([start (file-size dest-exe)])
|
||||
(call-with-output-file* dest-exe write-module
|
||||
#:exists 'append)
|
||||
(values start (file-size dest-exe))))])
|
||||
(+ start (bytes-length s))
|
||||
#f))))
|
||||
;; Unix starter: Maybe ELF, in which case we
|
||||
;; can add a proper section
|
||||
(let-values ([(s e p)
|
||||
(if unix-starter?
|
||||
(add-racket-section
|
||||
orig-exe
|
||||
dest-exe
|
||||
(if launcher? #".rackcmdl" #".rackprog")
|
||||
(lambda (start)
|
||||
(let ([s (open-output-bytes)])
|
||||
(write-module s)
|
||||
(let ([p (file-position s)])
|
||||
(display (make-starter-cmdline
|
||||
(make-full-cmdline start (+ start p)))
|
||||
s)
|
||||
(values (get-output-bytes s) p)))))
|
||||
(values #f #f #f))])
|
||||
(if (and s e)
|
||||
;; ELF succeeded:
|
||||
(values s (+ s p) e)
|
||||
;; Otherwise, just add to the end of the file:
|
||||
(let ([start (file-size dest-exe)])
|
||||
(call-with-output-file* dest-exe write-module
|
||||
#:exists 'append)
|
||||
(values start (file-size dest-exe) #f)))))])
|
||||
(when verbose?
|
||||
(fprintf (current-error-port) "Setting command line\n"))
|
||||
(let ([start-s (number->string start)]
|
||||
[end-s (number->string end)])
|
||||
(let ([full-cmdline (append
|
||||
(if launcher?
|
||||
(if (and (eq? 'windows (system-type))
|
||||
keep-exe?)
|
||||
;; argv[0] replacement:
|
||||
(list (path->string
|
||||
(if relative?
|
||||
(relativize exe dest-exe values)
|
||||
exe)))
|
||||
;; No argv[0]:
|
||||
null)
|
||||
(list "-k" start-s end-s))
|
||||
cmdline)])
|
||||
(let ()
|
||||
(let ([full-cmdline (make-full-cmdline start end)])
|
||||
(when collects-path-bytes
|
||||
(when verbose?
|
||||
(fprintf (current-error-port) "Setting collection path\n"))
|
||||
|
@ -1218,27 +1263,12 @@
|
|||
(lambda () (find-cmdline
|
||||
"exeuctable type"
|
||||
#"bINARy tYPe:"))))]
|
||||
[cmdline
|
||||
(apply bytes-append
|
||||
(map (lambda (s)
|
||||
(bytes-append
|
||||
(cond
|
||||
[(path? s) (path->bytes s)]
|
||||
[else (string->bytes/locale s)])
|
||||
#"\0"))
|
||||
(append
|
||||
(list (if relative?
|
||||
(relativize exe dest-exe values)
|
||||
exe)
|
||||
(let ([dir (find-dll-dir)])
|
||||
(if dir
|
||||
(if relative?
|
||||
(relativize dir dest-exe values)
|
||||
dir)
|
||||
"")))
|
||||
full-cmdline)))]
|
||||
[cmdline (if cmdline-end
|
||||
#f
|
||||
(make-starter-cmdline full-cmdline))]
|
||||
[out (open-output-file dest-exe #:exists 'update)])
|
||||
(let ([cmdline-end (+ end (bytes-length cmdline))]
|
||||
(let ([old-cmdline-end cmdline-end]
|
||||
[cmdline-end (or cmdline-end (+ end (bytes-length cmdline)))]
|
||||
[write-num (lambda (n)
|
||||
(write-bytes (integer->integer-bytes n 4 #t #f) out))])
|
||||
(dynamic-wind
|
||||
|
@ -1260,9 +1290,10 @@
|
|||
(write-num (length full-cmdline))
|
||||
(write-num (if mred? 1 0))
|
||||
(flush-output out)
|
||||
(file-position out end)
|
||||
(write-bytes cmdline out)
|
||||
(flush-output out))
|
||||
(unless old-cmdline-end
|
||||
(file-position out end)
|
||||
(write-bytes cmdline out)
|
||||
(flush-output out)))
|
||||
(lambda ()
|
||||
(close-output-port out)))))]
|
||||
[else
|
||||
|
|
316
collects/compiler/private/elf.rkt
Normal file
316
collects/compiler/private/elf.rkt
Normal file
|
@ -0,0 +1,316 @@
|
|||
#lang racket/base
|
||||
|
||||
(provide add-racket-section)
|
||||
|
||||
(define 32BIT 1)
|
||||
(define 64BIT 2)
|
||||
|
||||
(define LITTLEEND 1)
|
||||
(define BIGEND 2)
|
||||
|
||||
(define SECTION-ALIGN 16) ; conservative?
|
||||
|
||||
(define SHT_PROGBITS 1)
|
||||
|
||||
(struct elf (ph-offset ph-esize ph-ecount
|
||||
sh-offset sh-esize sh-ecount
|
||||
class format sh-str-index)
|
||||
#:transparent)
|
||||
(struct section (name-offset offset size)
|
||||
#:transparent)
|
||||
(struct program (offset size)
|
||||
#:transparent)
|
||||
|
||||
(define (copy-port-bytes amt in out)
|
||||
(let ([get (min amt 4096)])
|
||||
(let ([s (read-bytes get in)])
|
||||
(unless (and (bytes? s)
|
||||
(= get (bytes-length s)))
|
||||
(error 'add-elf-section "file data copy failed"))
|
||||
(write-bytes s out))
|
||||
(unless (= get amt)
|
||||
(copy-port-bytes (- amt get) in out))))
|
||||
|
||||
(define (write-n-bytes amt out)
|
||||
(let ([put (min amt 4096)])
|
||||
(write-bytes (make-bytes put 0) out)
|
||||
(unless (= put amt)
|
||||
(write-n-bytes (- amt put) out))))
|
||||
|
||||
(define (round-up v align)
|
||||
(let ([d (modulo v align)])
|
||||
(if (zero? d)
|
||||
v
|
||||
(+ v (- align d)))))
|
||||
|
||||
(define (read-elf p fail-k k #:dump? [dump? #f])
|
||||
(define (stop) (raise "unexpected input"))
|
||||
(define (expect b)
|
||||
(eq? b (read-byte p)))
|
||||
(define (skip n)
|
||||
(for ([i (in-range n)])
|
||||
(when (eof-object? (read-byte p))
|
||||
(stop))))
|
||||
(define (read-a-byte)
|
||||
(let ([v (read-byte p)])
|
||||
(when (eof-object? v)
|
||||
(stop))
|
||||
v))
|
||||
(define (skip-half) (skip 2))
|
||||
(define (skip-word) (skip 4))
|
||||
(define (show v) (displayln v) v)
|
||||
;; Read ELF identification ---------------
|
||||
(if (not (and
|
||||
(expect #x7F)
|
||||
(expect (char->integer #\E))
|
||||
(expect (char->integer #\L))
|
||||
(expect (char->integer #\F))))
|
||||
;; Not an ELF binary
|
||||
(fail-k)
|
||||
;; Is an ELF binary:
|
||||
(let ([class (read-byte p)])
|
||||
(unless (or (= class 32BIT)
|
||||
(= class 64BIT))
|
||||
(stop))
|
||||
(let ([format (read-byte p)])
|
||||
(unless (or (= format LITTLEEND)
|
||||
(= format BIGEND))
|
||||
(stop))
|
||||
;; Set up multi-byte reading ---------------
|
||||
(let* ([read-word
|
||||
(lambda ()
|
||||
(let ([a (read-a-byte)]
|
||||
[b (read-a-byte)]
|
||||
[c (read-a-byte)]
|
||||
[d (read-a-byte)])
|
||||
(cond
|
||||
[(= format LITTLEEND)
|
||||
(bitwise-ior a
|
||||
(arithmetic-shift b 8)
|
||||
(arithmetic-shift c 16)
|
||||
(arithmetic-shift d 24))]
|
||||
[else
|
||||
(bitwise-ior d
|
||||
(arithmetic-shift c 8)
|
||||
(arithmetic-shift b 16)
|
||||
(arithmetic-shift a 24))])))]
|
||||
[read-xword
|
||||
(lambda ()
|
||||
(if (= class 32BIT)
|
||||
(read-word)
|
||||
(let ([b (read-bytes 8 p)])
|
||||
(if (and (bytes? b) (= 8 (bytes-length b)))
|
||||
(integer-bytes->integer b #f (= format BIGEND))
|
||||
(stop)))))]
|
||||
[read-half
|
||||
(lambda ()
|
||||
(let ([a (read-a-byte)]
|
||||
[b (read-a-byte)])
|
||||
(cond
|
||||
[(= format LITTLEEND)
|
||||
(bitwise-ior a
|
||||
(arithmetic-shift b 8))]
|
||||
[else
|
||||
(bitwise-ior b
|
||||
(arithmetic-shift a 8))])))]
|
||||
[skip-addr (lambda ()
|
||||
(skip (if (= class 32BIT) 4 8)))]
|
||||
[read-addr (lambda () (read-xword))]
|
||||
[read-off (lambda () (read-xword))])
|
||||
(skip 1) ; version
|
||||
(skip 9) ; padding
|
||||
(skip-half) ; type
|
||||
(skip-half) ; machine
|
||||
(skip-word) ; version
|
||||
(skip-addr) ; entry
|
||||
;; Read rest of ELF header -----------------
|
||||
(let ([ph-offset (read-off)]
|
||||
[sh-offset (read-off)]
|
||||
[flags (read-word)]
|
||||
[eh-size (read-half)]
|
||||
[ph-esize (read-half)]
|
||||
[ph-ecount (read-half)]
|
||||
[sh-esize (read-half)]
|
||||
[sh-ecount (read-half)]
|
||||
[sh-str-index (read-half)])
|
||||
;; Read sections ------------------------
|
||||
(let ([sections
|
||||
(for/list ([i (in-range sh-ecount)])
|
||||
(file-position p (+ sh-offset (* i sh-esize)))
|
||||
(let ([name-offset (read-word)]
|
||||
[type (read-word)]
|
||||
[flags (read-xword)]
|
||||
[addr (read-addr)]
|
||||
[offset (read-off)]
|
||||
[size (read-xword)]
|
||||
[link (read-word)]
|
||||
[info (read-word)]
|
||||
[align (read-xword)]
|
||||
[esize (read-xword)])
|
||||
(section name-offset offset size)))])
|
||||
;; Read program headers ------------------------
|
||||
(let ([programs
|
||||
(for/list ([i (in-range ph-ecount)])
|
||||
(file-position p (+ ph-offset (* i ph-esize)))
|
||||
(let ([type (read-word)]
|
||||
[flags (if (= class 32BIT)
|
||||
0
|
||||
(read-word))]
|
||||
[offset (read-off)]
|
||||
[vaddr (read-addr)]
|
||||
[paddr (read-addr)]
|
||||
[file-size (read-xword)])
|
||||
(program offset file-size)))])
|
||||
;; Load strings from string section ------------------------
|
||||
(let* ([str-section (list-ref sections sh-str-index)]
|
||||
[strs (begin
|
||||
(file-position p (section-offset str-section))
|
||||
(read-bytes (section-size str-section) p))])
|
||||
(when dump?
|
||||
(for ([s (in-list sections)])
|
||||
(printf "~s ~x ~x\n"
|
||||
(regexp-match #rx#"[^\0]*" strs (min (section-name-offset s)
|
||||
(bytes-length strs)))
|
||||
(section-offset s)
|
||||
(section-size s))))
|
||||
(k (elf ph-offset ph-esize ph-ecount
|
||||
sh-offset sh-esize sh-ecount
|
||||
class format sh-str-index)
|
||||
sections programs
|
||||
str-section strs))))))))))
|
||||
|
||||
(define (add-racket-section src-file dest-file section-name get-data)
|
||||
(call-with-input-file*
|
||||
src-file
|
||||
(lambda (in)
|
||||
(read-elf
|
||||
in
|
||||
(lambda () (values #f #f #f))
|
||||
(lambda (elf sections programs str-section strs)
|
||||
(let ([new-sec-pos (+ (elf-sh-offset elf)
|
||||
(* (elf-sh-esize elf) (elf-sh-ecount elf)))]
|
||||
[new-sec-delta (round-up (elf-sh-ecount elf) SECTION-ALIGN)]
|
||||
[new-str-pos (+ (section-offset str-section)
|
||||
(section-size str-section))]
|
||||
[new-str-delta (round-up (add1 (bytes-length section-name))
|
||||
SECTION-ALIGN)]
|
||||
[total-size (file-size src-file)]
|
||||
[class (elf-class elf)]
|
||||
[format (elf-format elf)])
|
||||
(let-values ([(a-pos a-delta b-pos b-delta)
|
||||
(if (new-sec-pos . < . new-str-pos)
|
||||
(values new-sec-pos new-sec-delta
|
||||
new-str-pos new-str-delta)
|
||||
(values new-str-pos new-str-delta
|
||||
new-sec-pos new-sec-delta))]
|
||||
[(data mid) (get-data (+ total-size new-str-delta new-sec-delta))])
|
||||
(call-with-output-file*
|
||||
dest-file
|
||||
#:exists 'truncate
|
||||
(lambda (out)
|
||||
(let* ([write-word
|
||||
(lambda (v)
|
||||
(if (= format LITTLEEND)
|
||||
(begin
|
||||
(write-byte (bitwise-and v #xFF) out)
|
||||
(write-byte (bitwise-and (arithmetic-shift v -8) #xFF) out)
|
||||
(write-byte (bitwise-and (arithmetic-shift v -16) #xFF) out)
|
||||
(write-byte (bitwise-and (arithmetic-shift v -24) #xFF) out))
|
||||
(begin
|
||||
(write-byte (bitwise-and (arithmetic-shift v -24) #xFF) out)
|
||||
(write-byte (bitwise-and (arithmetic-shift v -16) #xFF) out)
|
||||
(write-byte (bitwise-and (arithmetic-shift v -8) #xFF) out)
|
||||
(write-byte (bitwise-and v #xFF) out))))]
|
||||
[write-xword
|
||||
(lambda (v)
|
||||
(if (= class 32BIT)
|
||||
(write-word v)
|
||||
(display (integer->integer-bytes v 8 #f (= format BIGEND))
|
||||
out)))]
|
||||
[write-addr (lambda (v) (write-xword v))]
|
||||
[write-off (lambda (v) (write-xword v))]
|
||||
[write-half
|
||||
(lambda (v)
|
||||
(if (= format LITTLEEND)
|
||||
(begin
|
||||
(write-byte (bitwise-and v #xFF) out)
|
||||
(write-byte (bitwise-and (arithmetic-shift v -8) #xFF) out))
|
||||
(begin
|
||||
(write-byte (bitwise-and (arithmetic-shift v -8) #xFF) out)
|
||||
(write-byte (bitwise-and v #xFF) out))))]
|
||||
[adjust (lambda (offset)
|
||||
(if (offset . >= . a-pos)
|
||||
(if (offset . >= . b-pos)
|
||||
(+ offset a-delta b-delta)
|
||||
(+ offset a-delta))
|
||||
offset))]
|
||||
[adjust* (lambda (offset)
|
||||
(add1 (adjust (sub1 offset))))]
|
||||
[at-class (lambda (a b) (if (= class 32BIT) a b))])
|
||||
|
||||
(file-position in 0)
|
||||
(copy-port-bytes a-pos in out)
|
||||
(write-n-bytes a-delta out)
|
||||
(copy-port-bytes (- b-pos a-pos) in out)
|
||||
(write-n-bytes b-delta out)
|
||||
(copy-port-bytes (- total-size b-pos) in out)
|
||||
|
||||
;; Write new section:
|
||||
(file-position out (adjust* new-sec-pos))
|
||||
(write-word (section-size str-section))
|
||||
(write-word SHT_PROGBITS)
|
||||
(write-xword 0) ; flags
|
||||
(write-addr 0) ; addr
|
||||
(write-off (+ total-size new-sec-delta new-str-delta))
|
||||
(write-xword (bytes-length data))
|
||||
(write-word 0) ; link
|
||||
(write-word 0) ; info
|
||||
(write-xword 1) ; align
|
||||
(write-xword 0) ; esize
|
||||
|
||||
;; Write new string:
|
||||
(file-position out (adjust* new-str-pos))
|
||||
(write-bytes section-name out)
|
||||
|
||||
;; Fix section-header and program-header offsets:
|
||||
(file-position out (at-class 28 32))
|
||||
(write-off (adjust (elf-ph-offset elf)))
|
||||
(write-off (adjust (elf-sh-offset elf)))
|
||||
|
||||
;; Increment section count:
|
||||
(file-position out (at-class 48 60))
|
||||
(write-half (add1 (length sections)))
|
||||
|
||||
;; Increment string section size:
|
||||
(file-position out (adjust (+ (elf-sh-offset elf)
|
||||
(* (elf-sh-str-index elf)
|
||||
(elf-sh-esize elf))
|
||||
(at-class 20 32))))
|
||||
(write-xword (+ (section-size str-section) new-str-delta))
|
||||
|
||||
;; Fix up section offsets:
|
||||
(for ([s (in-list sections)]
|
||||
[i (in-naturals)])
|
||||
(let ([offset (section-offset s)])
|
||||
(when (offset . > . a-pos)
|
||||
(file-position out (adjust (+ (elf-sh-offset elf)
|
||||
(* i (elf-sh-esize elf))
|
||||
(at-class 16 24))))
|
||||
(write-off (adjust offset)))))
|
||||
|
||||
;; Fix up program offsets:
|
||||
(for ([p (in-list programs)]
|
||||
[i (in-naturals)])
|
||||
(let ([offset (program-offset p)])
|
||||
(when (offset . > . a-pos)
|
||||
(file-position out (adjust (+ (elf-ph-offset elf)
|
||||
(* i (elf-ph-esize elf))
|
||||
(at-class 4 8))))
|
||||
(write-off (adjust offset)))))
|
||||
|
||||
;; Write new section data:
|
||||
(let ([dest (+ total-size new-sec-delta new-str-delta)])
|
||||
(file-position out dest)
|
||||
(write-bytes data out)
|
||||
|
||||
(values dest (+ dest (bytes-length data)) mid))))))))))))
|
|
@ -24,6 +24,13 @@
|
|||
exe_path - program to start (relative is w.r.t. executable)
|
||||
dll_path - DLL directory if non-empty (relative is w.r.t. executable)
|
||||
cmdline_arg ...
|
||||
|
||||
For ELF binaries, the absolute values of `start', `prog_end', and
|
||||
`end' are ignored if a ".rackcmdl" (starter) or ".rackprog"
|
||||
(embedding) section is found. The `start' value is set to match the
|
||||
section offset, and `prog_end' and `end' are correspondingly
|
||||
adjusted. Using a seciton offset allows linking tools (such as
|
||||
`strip') to move the data in the executable.
|
||||
*/
|
||||
char *config = "cOnFiG:[***************************";
|
||||
|
||||
|
@ -101,8 +108,6 @@ static int write_str(int fd, char *s)
|
|||
return write(fd, s, strlen(s));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Useful for debugging: */
|
||||
static char *num_to_string(int n)
|
||||
{
|
||||
if (!n)
|
||||
|
@ -118,7 +123,6 @@ static char *num_to_string(int n)
|
|||
return d;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *string_append(char *s1, char *s2)
|
||||
{
|
||||
|
@ -225,12 +229,100 @@ static char *next_string(char *s)
|
|||
return s + strlen(s) + 1;
|
||||
}
|
||||
|
||||
typedef unsigned short ELF__Half;
|
||||
typedef unsigned int ELF__Word;
|
||||
typedef unsigned long ELF__Xword;
|
||||
typedef unsigned long ELF__Addr;
|
||||
typedef unsigned long ELF__Off;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[16];
|
||||
ELF__Half e_type;
|
||||
ELF__Half e_machine;
|
||||
ELF__Word e_version;
|
||||
ELF__Addr e_entry;
|
||||
ELF__Off e_phoff;
|
||||
ELF__Off e_shoff;
|
||||
ELF__Word e_flags;
|
||||
ELF__Half e_ehsize;
|
||||
ELF__Half e_phentsize;
|
||||
ELF__Half e_phnum;
|
||||
ELF__Half e_shentsize;
|
||||
ELF__Half e_shnum;
|
||||
ELF__Half e_shstrndx;
|
||||
} ELF__Header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ELF__Word sh_name;
|
||||
ELF__Word sh_type;
|
||||
ELF__Xword sh_flags;
|
||||
ELF__Addr sh_addr;
|
||||
ELF__Off sh_offset;
|
||||
ELF__Xword sh_size;
|
||||
ELF__Word sh_link;
|
||||
ELF__Word sh_info;
|
||||
ELF__Xword sh_addralign;
|
||||
ELF__Xword sh_entsize;
|
||||
} Elf__Shdr;
|
||||
|
||||
static int try_elf_section(const char *me, int *_start, int *_prog_end, int *_end)
|
||||
{
|
||||
int fd, i;
|
||||
ELF__Header e;
|
||||
Elf__Shdr s;
|
||||
char *strs;
|
||||
|
||||
fd = open(me, O_RDONLY, 0);
|
||||
if (fd == -1) return 0;
|
||||
|
||||
if (read(fd, &e, sizeof(e)) == sizeof(e)) {
|
||||
if ((e.e_ident[0] == 0x7F)
|
||||
&& (e.e_ident[1] == 'E')
|
||||
&& (e.e_ident[2] == 'L')
|
||||
&& (e.e_ident[3] == 'F')) {
|
||||
|
||||
lseek(fd, e.e_shoff + (e.e_shstrndx * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strs = (char *)malloc(s.sh_size);
|
||||
lseek(fd, s.sh_offset, SEEK_SET);
|
||||
if (read(fd, strs, s.sh_size) != s.sh_size) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < e.e_shnum; i++) {
|
||||
lseek(fd, e.e_shoff + (i * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(strs + s.sh_name, ".rackcmdl")
|
||||
|| !strcmp(strs + s.sh_name, ".rackprog")) {
|
||||
*_prog_end = (*_prog_end - *_start) + s.sh_offset;
|
||||
*_start = s.sh_offset;
|
||||
*_end = s.sh_offset + s.sh_size;
|
||||
close(fd);
|
||||
return !strcmp(strs + s.sh_name, ".rackprog");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *me = argv[0], *data, **new_argv;
|
||||
char *exe_path, *lib_path, *dll_path;
|
||||
int start, prog_end, end, count, fd, v, en, x11;
|
||||
int argpos, inpos, collcount = 1;
|
||||
int argpos, inpos, collcount = 1, fix_argv;
|
||||
|
||||
if (config[7] == '[') {
|
||||
write_str(2, argv[0]);
|
||||
|
@ -314,6 +406,8 @@ int main(int argc, char **argv)
|
|||
count = as_int(config + 20);
|
||||
x11 = as_int(config + 24);
|
||||
|
||||
fix_argv = try_elf_section(me, &start, &prog_end, &end);
|
||||
|
||||
{
|
||||
int offset, len;
|
||||
offset = _coldir_offset;
|
||||
|
@ -407,6 +501,12 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (fix_argv) {
|
||||
/* next three args are "-k" and numbers; fix
|
||||
the numbers to match start and prog_end */
|
||||
fix_argv = argpos + 1;
|
||||
}
|
||||
|
||||
/* Add built-in flags: */
|
||||
while (count--) {
|
||||
new_argv[argpos++] = data;
|
||||
|
@ -420,6 +520,11 @@ int main(int argc, char **argv)
|
|||
|
||||
new_argv[argpos] = NULL;
|
||||
|
||||
if (fix_argv) {
|
||||
new_argv[fix_argv] = num_to_string(start);
|
||||
new_argv[fix_argv+1] = num_to_string(prog_end);
|
||||
}
|
||||
|
||||
/* Execute the original binary: */
|
||||
|
||||
v = execv(exe_path, new_argv);
|
||||
|
|
Loading…
Reference in New Issue
Block a user