2013-03-24 17 views
8

Bir metin dosyasının bir ikili formunu yürütülebilir dosyaya eklemek için objcopy kullanıyorum. (Çalışma zamanında dosyaya bir dize olarak ihtiyacım var). Bu, linker sembol isimlerinden referansları bulmak için gerekli olana kadar iyi çalışır. Sorun şu ki, objcopy sembol isimlerini dosya yoluna yol adı ile ekliyor. Paketin gönderilmesi için GNU Autotools'u kullandığım için bu değiştirilmiş yol adı değişiyor ve C/C++ programında hangi harici linker sembolünün kullanılacağını bilmiyorum.objcopy, dizin yol adını sembol adına önceden gönderir

SUFFIXES = .txt 
.txt.$(OBJEXT): 
    objcopy --input binary --output elf32-i386 --binary-architecture i386 $< [email protected] 

nasıl sadece bize bağlayıcı sembolleri olarak dosya adının sapı objcopy söyleyebilir:

nm libtest.a |grep textfile 
textfile.o: 
00001d21 D _binary__home_git_textfile_end 
00001d21 A _binary__home_git_textfile_size 
00000000 D _binary__home_git_textfile_start 

libtest.a (Makefile.am gelen ekstresi) ile üretildi? Yoksa problemin başka bir yolu var mı?

cevap

0

Basit bir çözüm, metin dosyanızı bir dizi karakter dizisini başlatmak için kullanılabilecek bir şekle dönüştürmektir. Yani, "ABC012" için 0x41,0x42,0x43,0x30,0x31,0x32 elde edersiniz. Daha sonra bu bayt dizisini ekleyebilirsin. Ayrıca, her şeyi metne dönüştürmek yerine, tüm ASCII olmayan karakterleri kaçış olarak ekleyebilirsiniz, böylece metnin çoğu oluşturulan dahili dosyada okunabilir durumda kalır. Ben objcopy kullanırsanız

+0

“stdin” ve “extern” işlevlerini kullanmak kaynağın saklanmasını engeller. – Alex

+0

@Alex Ne demek istediğimi anladığımdan emin değilim. –

+0

'-x ' ve '-' gcc' /' g ++ için girdi olarak – Alex

7

Biraz ironik başka dizininde bir PNG gelen bir nesne dosyası oluşturmak için

... sembollerin yeniden adlandırılmasını verir --redefine-sym seçeneği aracılığıyla sorunu çözmek için objcopy kullanabilirsiniz:

$ objcopy -I binary -O elf64-x86-64 -B i386 --rename-section .data=.rodata,alloc,load,data,contents,readonly ../../resources/test.png test_png.o 

elde edilen nesne, aşağıdaki semboller var

$readelf -s test_png.o -W 

Symbol table '.symtab' contains 5 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 SECTION LOCAL DEFAULT 1 
    2: 0000000000000000  0 NOTYPE GLOBAL DEFAULT 1 _binary_______resources_test_png_start 
    3: 0000000000003aaa  0 NOTYPE GLOBAL DEFAULT 1 _binary_______resources_test_png_end 
    4: 0000000000003aaa  0 NOTYPE GLOBAL DEFAULT ABS _binary_______resources_test_png_size 

Bunlar daha sonra yeniden adlandırılabilir:

$readelf -s test_png.o -W 

Symbol table '.symtab' contains 5 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 SECTION LOCAL DEFAULT 1 
    2: 0000000000000000  0 NOTYPE GLOBAL DEFAULT 1 _binary_test_png_start 
    3: 0000000000003aaa  0 NOTYPE GLOBAL DEFAULT 1 _binary_test_png_end 
    4: 0000000000003aaa  0 NOTYPE GLOBAL DEFAULT ABS _binary_test_png_size 
+0

'--redefine-sym '' den bahsetmek iyi bir şey, ama yetersiz görünüyor: objektifin arayanı nasıl" orjinal "sembolü nasıl oluşturacağını bilmesi gerekiyor isim? Giriş dosyası için “../../ foo/bar.txt” gibi bir şey varsa, sembolün adı _binary ________ foo_bar_txt_start' gibi korkunç bir şeydir. Noktaları, eğik çizgileri ve belki de diğer karakterleri (ki?) Alt çizgilere dönüştürmek için mantığı kodlamak zorunda kalmak oldukça aptalca görünüyor. Ve tuhaf olarak, objcopy'un '--wildcard' seçeneği bize yardımcı olabilir, ama '--redefine-sym' ile hiçbir etkisi olmayacak gibi görünüyor (sanırım diğer kullanımlar için niyet ediyorlar). –

+3

@JohnZwinck: Sadece dizini olmayan bölümü yeniden yapılandırabilmelisiniz, daha sonra isimler için itiraz edin ve istediğiniz isimde biten işareti kontrol edin ve sonra yeniden adlandırmak için kullanın. – PlasmaHH

+0

Kod bakıldığında, tüm alfanümerik olmayan karakterler '_' olarak dönüştürülür. Yani aşağıdaki dosya adında "echo -n" $ filename "| tr -c '[A-Za-z0-9]' '_'. '_binary_' öğesini yerleştirin ve '_start' ve diğerlerini ekleyin. – Mitar

7

Jenerik:

$objcopy --redefine-sym _binary_______resources_test_png_start=_binary_test_png_start test_png.o 
$objcopy --redefine-sym _binary_______resources_test_png_size=_binary_test_png_size test_png.o 
$objcopy --redefine-sym _binary_______resources_test_png_end=_binary_test_png_end test_png.o 

objcopy PNG geçerli dizinde bulunan olsaydı oluşturulan olurdu sembol adları ile bir nesne sonuçlanan Ham verilerin ELF'ye dahil edilmesi metodu .incbin assembler direktifiyle desteklenir.

Bu dosya cpp'de aracılığıyla önişlemdedir
 .global foo_start 
foo_start: 
     .incbin "foo.raw" 

     .global foo_end 
foo_end:  

yüzden, orada örneğin dosya adı hardcode gerekmez:

hüner şablon aşağıdaki gibi görünebilir .S dosyası oluşturmaktır. derleme yaparken

 .incbin __raw_file_path__ 

... sonra geçmek: yazabiliriz

gcc -D__raw_file_path__='"data/foo.png"' foo.S -c -o data/foo.o 

Son olarak, .S kendimizi dosyası hazırlanırken bazı ekstra veri ve/veya bilgi ekleyebilirsiniz.Eğer ham "metin dosyaları" include ve isterseniz bu ekleyebilir C dizeleri olarak kullanılabilir olması için '0' sadece ham verilere sonra bayt:

 .global foo_start 
foo_start: 
     .incbin "foo.raw" 

     .global foo_end 
foo_end:  
     .byte 0 

     .global foo_size 
foo_size: 
     .int foo_end - foo_start 

Eğer tam gelişmiş esneklik istiyorsanız, ders ön- can Örneğin, herhangi bir parçasını değiştirmek için manuel olarak işlem yapın.

sed -e "s,@[email protected],passwd,g" -e "s,@[email protected],/etc/passwd," <foo.S.in | gcc -x assembler-with-cpp - -o passwd.o -c 
İlgili konular