@@ -57,6 +57,7 @@ intptr_t option_mem_lb = RELATIVE_ADDRESS_MIN;
5757intptr_t option_mem_ub = RELATIVE_ADDRESS_MAX;
5858size_t option_mem_mapping_size = PAGE_SIZE;
5959bool option_mem_multi_page = true ;
60+ intptr_t option_mem_rebase = 0x0 ;
6061std::set<intptr_t > option_trap;
6162bool option_trap_all = false ;
6263bool option_trap_entry = false ;
@@ -65,6 +66,7 @@ static std::string option_output("-");
6566bool option_loader_base_set = false ;
6667bool option_loader_phdr_set = false ;
6768bool option_loader_static_set = false ;
69+ bool option_mem_rebase_set = false ;
6870
6971/*
7072 * Global statistics.
@@ -140,7 +142,7 @@ void debugImpl(const char *msg, ...)
140142 * Parse an integer from an optarg.
141143 */
142144static intptr_t parseIntOptArg (const char *option, const char *optarg,
143- intptr_t lb, intptr_t ub)
145+ intptr_t lb, intptr_t ub, bool hex = false )
144146{
145147 const char *optarg_0 = optarg;
146148 bool neg = (optarg[0 ] == ' -' );
@@ -155,8 +157,18 @@ static intptr_t parseIntOptArg(const char *option, const char *optarg,
155157 r = (neg? -r: r);
156158 if (errno != 0 || end == optarg ||
157159 (end != nullptr && *end != ' \0 ' ) || r < lb || r > ub)
158- error (" failed to parse argument \" %s\" for the `%s' option; "
159- " expected a number %zd..%zd" , option, optarg_0, lb, ub);
160+ {
161+ if (!hex)
162+ error (" failed to parse argument \" %s\" for the `%s' option; "
163+ " expected a number within the range %zd..%zd" , option,
164+ optarg_0, lb, ub);
165+ else
166+ error (" failed to parse argument \" %s\" for the `%s' option; "
167+ " expected a number within the range %s0x%lx..%s0x%lx" ,
168+ option, optarg_0,
169+ (lb < 0 ? " -" : " " ), std::abs (lb),
170+ (ub < 0 ? " -" : " " ), std::abs (ub));
171+ }
160172 return r;
161173}
162174
@@ -281,6 +293,13 @@ static void usage(FILE *stream, const char *progname)
281293 " \t\t Enable [disable] trampolines that cross page boundaries.\n "
282294 " \t\t Default: true (enabled)\n "
283295 " \n "
296+ " \t --mem-rebase[=ADDR]\n "
297+ " \t\t Rebase the binary to the absolute address ADDR. Only\n "
298+ " \t\t relevant for Windows PE binaries. The special value \" auto\"\n "
299+ " \t\t will cause a suitable base address to be chose automatically.\n "
300+ " \t\t The special value \" none\" leaves the original base intact.\n "
301+ " \t\t Default: none (disabled)\n "
302+ " \n "
284303 " \t --tactic-B1[=false]\n "
285304 " \t --tactic-B2[=false]\n "
286305 " \t --tactic-T1[=false]\n "
@@ -327,6 +346,7 @@ enum Option
327346 OPTION_MEM_LB,
328347 OPTION_MEM_MAPPING_SIZE,
329348 OPTION_MEM_MULTI_PAGE,
349+ OPTION_MEM_REBASE,
330350 OPTION_MEM_UB,
331351 OPTION_OEPILOGUE,
332352 OPTION_OEPILOGUE_SIZE,
@@ -374,6 +394,7 @@ void parseOptions(int argc, char * const argv[], bool api)
374394 {" mem-lb" , req_arg, nullptr , OPTION_MEM_LB},
375395 {" mem-mapping-size" , req_arg, nullptr , OPTION_MEM_MAPPING_SIZE},
376396 {" mem-multi-page" , opt_arg, nullptr , OPTION_MEM_MULTI_PAGE},
397+ {" mem-rebase" , req_arg, nullptr , OPTION_MEM_REBASE},
377398 {" mem-ub" , req_arg, nullptr , OPTION_MEM_UB},
378399 {" output" , req_arg, nullptr , OPTION_OUTPUT},
379400 {" tactic-B1" , opt_arg, nullptr , OPTION_TACTIC_B1},
@@ -480,7 +501,7 @@ void parseOptions(int argc, char * const argv[], bool api)
480501 break ;
481502 case OPTION_TRAP:
482503 option_trap.insert (parseIntOptArg (" --trap" , optarg, 0 ,
483- INTPTR_MAX));
504+ INTPTR_MAX, /* hex= */ true ));
484505 break ;
485506 case OPTION_TRAP_ALL:
486507 option_trap_all = parseBoolOptArg (" --trap-all" , optarg);
@@ -491,7 +512,7 @@ void parseOptions(int argc, char * const argv[], bool api)
491512 case OPTION_LOADER_BASE:
492513 option_loader_base_set = true ;
493514 option_loader_base = parseIntOptArg (" --loader-base" , optarg,
494- 0x0 , 0x800000000 );
515+ 0x0 , 0x800000000 , /* hex= */ true );
495516 if (option_loader_base % PAGE_SIZE != 0 )
496517 error (" failed to parse argument \" %s\" for the "
497518 " `--loader-base' option; the loader base address "
@@ -533,11 +554,11 @@ void parseOptions(int argc, char * const argv[], bool api)
533554 break ;
534555 case OPTION_MEM_LB:
535556 option_mem_lb = parseIntOptArg (" --mem-lb" , optarg,
536- RELATIVE_ADDRESS_MIN, RELATIVE_ADDRESS_MAX);
557+ RELATIVE_ADDRESS_MIN, RELATIVE_ADDRESS_MAX, /* hex= */ true );
537558 break ;
538559 case OPTION_MEM_UB:
539560 option_mem_ub = parseIntOptArg (" --mem-ub" , optarg,
540- RELATIVE_ADDRESS_MIN, RELATIVE_ADDRESS_MAX);
561+ RELATIVE_ADDRESS_MIN, RELATIVE_ADDRESS_MAX, /* hex= */ true );
541562 break ;
542563 case OPTION_MEM_MAPPING_SIZE:
543564 option_mem_mapping_size = parseIntOptArg (" --mem-mapping-size" ,
@@ -557,6 +578,16 @@ void parseOptions(int argc, char * const argv[], bool api)
557578 option_mem_multi_page =
558579 parseBoolOptArg (" --mem-multi-page" , optarg);
559580 break ;
581+ case OPTION_MEM_REBASE:
582+ option_mem_rebase_set = true ;
583+ if (strcmp (optarg, " auto" ) == 0 )
584+ option_mem_rebase = -1 ;
585+ else if (strcmp (optarg, " none" ) == 0 )
586+ option_mem_rebase = 0x0 ;
587+ else
588+ option_mem_rebase = parseIntOptArg (" --mem-rebase" , optarg,
589+ 0x100000000ll , 0xffff00000000ll , /* hex=*/ true );
590+ break ;
560591 default :
561592 error (" failed to parse command-line options; try `--help' "
562593 " for more information" );
0 commit comments