@@ -1075,6 +1075,33 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot)
1075
1075
}
1076
1076
}
1077
1077
1078
+ #ifdef CONFIG_USE_FDPIC
1079
+ static abi_ulong loader_build_fdpic_loadmap (struct image_info * info , abi_ulong sp )
1080
+ {
1081
+ uint16_t n ;
1082
+ struct elf32_fdpic_loadseg * loadsegs = info -> loadsegs ;
1083
+
1084
+ /* elf32_fdpic_loadseg */
1085
+ n = info -> nsegs ;
1086
+ while (n -- ) {
1087
+ sp -= 12 ;
1088
+ put_user_u32 (loadsegs [n ].addr , sp + 0 );
1089
+ put_user_u32 (loadsegs [n ].p_vaddr , sp + 4 );
1090
+ put_user_u32 (loadsegs [n ].p_memsz , sp + 8 );
1091
+ }
1092
+
1093
+ /* elf32_fdpic_loadmap */
1094
+ sp -= 4 ;
1095
+ put_user_u16 (0 , sp + 0 ); /* version */
1096
+ put_user_u16 (info -> nsegs , sp + 2 ); /* nsegs */
1097
+
1098
+ info -> personality = PER_LINUX_FDPIC ;
1099
+ info -> loadmap_addr = sp ;
1100
+
1101
+ return sp ;
1102
+ }
1103
+ #endif
1104
+
1078
1105
static abi_ulong create_elf_tables (abi_ulong p , int argc , int envc ,
1079
1106
struct elfhdr * exec ,
1080
1107
struct image_info * info ,
@@ -1087,6 +1114,21 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
1087
1114
const int n = sizeof (elf_addr_t );
1088
1115
1089
1116
sp = p ;
1117
+
1118
+ #ifdef CONFIG_USE_FDPIC
1119
+ /* Needs to be before we load the env/argc/... */
1120
+ if (elf_is_fdpic (exec )) {
1121
+ /* Need 4 byte alignment for these structs */
1122
+ sp &= ~3 ;
1123
+ sp = loader_build_fdpic_loadmap (info , sp );
1124
+ info -> other_info = interp_info ;
1125
+ if (interp_info ) {
1126
+ interp_info -> other_info = info ;
1127
+ sp = loader_build_fdpic_loadmap (interp_info , sp );
1128
+ }
1129
+ }
1130
+ #endif
1131
+
1090
1132
u_platform = 0 ;
1091
1133
k_platform = ELF_PLATFORM ;
1092
1134
if (k_platform ) {
@@ -1197,6 +1239,11 @@ static void load_elf_image(const char *image_name, int image_fd,
1197
1239
}
1198
1240
bswap_phdr (phdr , ehdr -> e_phnum );
1199
1241
1242
+ #ifdef CONFIG_USE_FDPIC
1243
+ info -> nsegs = 0 ;
1244
+ info -> pt_dynamic_addr = 0 ;
1245
+ #endif
1246
+
1200
1247
/* Find the maximum size of the image and allocate an appropriate
1201
1248
amount of memory to handle that. */
1202
1249
loaddr = -1 , hiaddr = 0 ;
@@ -1210,6 +1257,9 @@ static void load_elf_image(const char *image_name, int image_fd,
1210
1257
if (a > hiaddr ) {
1211
1258
hiaddr = a ;
1212
1259
}
1260
+ #ifdef CONFIG_USE_FDPIC
1261
+ ++ info -> nsegs ;
1262
+ #endif
1213
1263
}
1214
1264
}
1215
1265
@@ -1290,6 +1340,27 @@ static void load_elf_image(const char *image_name, int image_fd,
1290
1340
}
1291
1341
load_bias = load_addr - loaddr ;
1292
1342
1343
+ #ifdef CONFIG_USE_FDPIC
1344
+ {
1345
+ struct elf32_fdpic_loadseg * loadsegs = info -> loadsegs =
1346
+ qemu_malloc (sizeof (* loadsegs ) * info -> nsegs );
1347
+
1348
+ for (i = 0 ; i < ehdr -> e_phnum ; ++ i ) {
1349
+ switch (phdr [i ].p_type ) {
1350
+ case PT_DYNAMIC :
1351
+ info -> pt_dynamic_addr = phdr [i ].p_vaddr + load_bias ;
1352
+ break ;
1353
+ case PT_LOAD :
1354
+ loadsegs -> addr = phdr [i ].p_vaddr + load_bias ;
1355
+ loadsegs -> p_vaddr = phdr [i ].p_vaddr ;
1356
+ loadsegs -> p_memsz = phdr [i ].p_memsz ;
1357
+ ++ loadsegs ;
1358
+ break ;
1359
+ }
1360
+ }
1361
+ }
1362
+ #endif
1363
+
1293
1364
info -> load_bias = load_bias ;
1294
1365
info -> load_addr = load_addr ;
1295
1366
info -> entry = ehdr -> e_entry + load_bias ;
0 commit comments