Хорошо ... Извините за задержку, но мне пришлось немного подумать об этом ...
Я не уверен, что вы можете сделать это [полностью] только с помощью сценария компоновщика. Это может быть возможным, но я думаю, что есть более простой / более надежный способ [с небольшой дополнительной подготовкой]
Метод, который я использовал ранее, состоит в том, чтобы скомпилировать с -S
, чтобы получить .s
файл. Измените это. И затем, скомпилируйте измененный .s
Обратите внимание, что у вас могут возникнуть проблемы с глобальным подобным:
int B;
Это приведет go к .comm
разделу в ASM источник. Это не может быть идеальным.
Для инициализированных данных:
int B = 23;
Вы можете добавить атрибут раздела, чтобы принудительно перенести его в специальный раздел. В противном случае он окажется в секции .data
Так что я мог бы избегать секций .comm
и / или .bss
в пользу всегда с использованием инициализированных данных. Это потому, что .comm
имеет ту же проблему, что и .rodata
(то есть он заканчивается как один большой шарик).
В любом случае, ниже приведен пошаговый процесс.
I поместите макросы с именем раздела в общий файл (например) sctname.h
:
#define _SCTJOIN(_pre,_sct) _pre #_sct
#define _TXTSCT(_sct) __attribute__((section(_SCTJOIN(".txt",_sct))))
#define _DATSCT(_sct) __attribute__((section(_SCTJOIN(".dat",_sct))))
#ifdef SCTNO
#define TXTSCT _TXTSCT(SCTNO)
#define DATSCT _DATSCT(SCTNO)
#endif
Вот немного измененная версия вашего .c
файла (например, module.c
):
#include <stdio.h>
#ifndef SCTNO
#define SCTNO 152
#endif
#include "sctname.h"
int B DATSCT = 23;
TXTSCT void
TestFunc(int A)
{
printf("%d Squared Is: %d\r\n", A, A * A * B);
}
Чтобы создать файл .s
, мы делаем:
cc -S -Wall -Werror -O2 module.c
Фактическое имя / номер раздела можно указать в командной строке:
cc -S -Wall -Werror -O2 -DSCTNO=152 module.c
Это дает нам module.s
:
.file "module.c"
.text
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d Squared Is: %d\r\n"
.section .txt152,"ax",@progbits
.p2align 4,,15
.globl TestFunc
.type TestFunc, @function
TestFunc:
.LFB11:
.cfi_startproc
movl %edi, %edx
movl %edi, %esi
xorl %eax, %eax
imull %edi, %edx
movl $.LC0, %edi
imull B(%rip), %edx
jmp printf
.cfi_endproc
.LFE11:
.size TestFunc, .-TestFunc
.globl B
.section .dat152,"aw"
.align 4
.type B, @object
.size B, 4
B:
.long 23
.ident "GCC: (GNU) 8.3.1 20190223 (Red Hat 8.3.1-2)"
.section .note.GNU-stack,"",@progbits
Теперь мы должны прочитать .s
и изменить его. Я создал скрипт perl, который делает это (например, rofix
):
#!/usr/bin/perl
master(@ARGV);
exit(0);
sub master
{
my(@argv) = @_;
$root = shift(@argv);
$root =~ s/[.][^.]+$//;
$sfile = "$root.s";
$ofile = "$root.TMP";
open($xfsrc,"<$sfile") or
die("rofix: unable to open '$sfile' -- $!\n");
open($xfdst,">$ofile") or
die("rofix: unable to open '$sfile' -- $!\n");
$txtpre = "^[.]txt";
$datpre = "^[.]dat";
# find the text and data sections
seek($xfsrc,0,0);
while ($bf = <$xfsrc>) {
chomp($bf);
if ($bf =~ /^\s*[.]section\s(\S+)/) {
$sctcur = $1;
sctget($txtpre);
sctget($datpre);
}
}
# modify the data sections
seek($xfsrc,0,0);
while ($bf = <$xfsrc>) {
chomp($bf);
if ($bf =~ /^\s*[.]section\s(\S+)/) {
$sctcur = $1;
sctfix();
print($xfdst $bf,"\n");
next;
}
print($xfdst $bf,"\n");
}
close($xfsrc);
close($xfdst);
system("diff -u $sfile $ofile");
rename($ofile,$sfile) or
die("rofix: unable to rename '$ofile' to '$sfile' -- $!\n");
}
sub sctget
{
my($pre) = @_;
my($sctname,@sct);
{
last unless (defined($pre));
@sct = split(",",$sctcur);
$sctname = shift(@sct);
last unless ($sctname =~ /$pre/);
printf("sctget: FOUND %s\n",$sctname);
$sct_lookup{$pre} = $sctname;
}
}
sub sctfix
{
my($sctname,@sct);
my($sctnew);
{
last unless ($sctcur =~ /^[.]rodata/);
$sctnew = $sct_lookup{$txtpre};
last unless (defined($sctnew));
@sct = split(",",$sctcur);
$sctname = shift(@sct);
$sctname .= $sctnew;
unshift(@sct,$sctname);
$sctname = join(",",@sct);
$bf = sprintf("\t.section\t%s",$sctname);
}
}
Разница между старым и новым module.s
составляет:
sctget: FOUND .txt152
sctget: FOUND .dat152
--- module.s 2020-04-20 19:02:23.777302484 -0400
+++ module.TMP 2020-04-20 19:06:33.631926065 -0400
@@ -1,6 +1,6 @@
.file "module.c"
.text
- .section .rodata.str1.1,"aMS",@progbits,1
+ .section .rodata.txt152,"aMS",@progbits,1
.LC0:
.string "%d Squared Is: %d\r\n"
.section .txt152,"ax",@progbits
Итак, теперь создайте .o
с:
cc -c module.s
Для make-файла это может быть что-то вроде [с некоторыми символами подстановки]:
module.o: module.c
cc -S -Wall -Werror -O2 module.c
./rofix module.s
cc -c module.s
Теперь вы можете добавить соответствующие места размещения в своем скрипте компоновщика для [вашего исходного раздела] .txt152
и нового .rodata.txt152
.
И, для раздела инициализированных данных .dat152
Обратите внимание, что фактические соглашения об именах являются произвольными. Если вы хотите изменить их, просто измените rofix
[и скрипт компоновщика] соответствующим образом
Вот вывод readelf -a
для module.o
:
Обратите внимание, что есть также .rela.txt152
раздел!?!?
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 808 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 15
Section header string table index: 14
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000000 0000000000000000 AX 0 0 1
[ 2] .data PROGBITS 0000000000000000 00000040
0000000000000000 0000000000000000 WA 0 0 1
[ 3] .bss NOBITS 0000000000000000 00000040
0000000000000000 0000000000000000 WA 0 0 1
[ 4] .rodata.txt152 PROGBITS 0000000000000000 00000040
0000000000000014 0000000000000001 AMS 0 0 1
[ 5] .txt152 PROGBITS 0000000000000000 00000060
000000000000001a 0000000000000000 AX 0 0 16
[ 6] .rela.txt152 RELA 0000000000000000 00000250
0000000000000048 0000000000000018 I 12 5 8
[ 7] .dat152 PROGBITS 0000000000000000 0000007c
0000000000000004 0000000000000000 WA 0 0 4
[ 8] .comment PROGBITS 0000000000000000 00000080
000000000000002d 0000000000000001 MS 0 0 1
[ 9] .note.GNU-stack PROGBITS 0000000000000000 000000ad
0000000000000000 0000000000000000 0 0 1
[10] .eh_frame PROGBITS 0000000000000000 000000b0
0000000000000030 0000000000000000 A 0 0 8
[11] .rela.eh_frame RELA 0000000000000000 00000298
0000000000000018 0000000000000018 I 12 10 8
[12] .symtab SYMTAB 0000000000000000 000000e0
0000000000000150 0000000000000018 13 11 8
[13] .strtab STRTAB 0000000000000000 00000230
000000000000001c 0000000000000000 0 0 1
[14] .shstrtab STRTAB 0000000000000000 000002b0
0000000000000078 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There is no dynamic section in this file.
Relocation section '.rela.txt152' at offset 0x250 contains 3 entries:
Offset Info Type Sym. Value Sym. Name + Addend
00000000000a 00050000000a R_X86_64_32 0000000000000000 .rodata.txt152 + 0
000000000011 000c00000002 R_X86_64_PC32 0000000000000000 B - 4
000000000016 000d00000004 R_X86_64_PLT32 0000000000000000 printf - 4
Relocation section '.rela.eh_frame' at offset 0x298 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000600000002 R_X86_64_PC32 0000000000000000 .txt152 + 0
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table '.symtab' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS module.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 4
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 9
9: 0000000000000000 0 SECTION LOCAL DEFAULT 10
10: 0000000000000000 0 SECTION LOCAL DEFAULT 8
11: 0000000000000000 26 FUNC GLOBAL DEFAULT 5 TestFunc
12: 0000000000000000 4 OBJECT GLOBAL DEFAULT 7 B
13: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
No version information found in this file.