Commit e44066b3 authored by Petteri Mäki's avatar Petteri Mäki
Browse files

shuffle-ld functionality

parent 6e256507
......@@ -666,7 +666,7 @@ Lex::one_char_operator(char c1)
}
// Skip a C style comment. *PP points to just after the "/*". Return
// false if the comment did not end.
// false if the comment did not end. */
bool
Lex::skip_c_comment(const char** pp)
......
......@@ -88,6 +88,7 @@ typedef enum
{
none, by_name, by_alignment, by_name_alignment, by_alignment_name,
by_none, by_init_priority
,SHUFFLE_OBFUSCATION
} sort_type;
extern sort_type sort_section;
......
......@@ -45,6 +45,8 @@
#include "plugin.h"
#endif /* ENABLE_PLUGINS */
#include "md5.h"
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER))
#endif
......@@ -411,6 +413,71 @@ get_init_priority (const char *name)
return 0;
}
typedef struct
{
uint32_t data[128/(8*sizeof(uint32_t))];
} md5_digest;
static struct md5_memory_entry
{
md5_digest digest;
char * str; // owned
struct md5_memory_entry * next;
} * md5_memory = NULL;
static bfd_boolean md5_collisions = FALSE;
static void
check_md5_memory (const char * str, const md5_digest * digest)
{
struct md5_memory_entry ** next_ptr = &md5_memory;
for (struct md5_memory_entry * entry = md5_memory; entry != NULL; entry = entry->next)
{
next_ptr = &entry->next;
if (memcmp ((const void *) digest, (const void *) &entry->digest, 128/8) == 0)
{
if (strcmp (str, entry->str) == 0)
return;
else if (!md5_collisions)
{
einfo (_("There are md5 collisions in shuffle obfuscation.\n"));
md5_collisions = TRUE;
}
}
}
/* The hash was not found in the memory. */
ASSERT (*next_ptr = (struct md5_memory_entry *) malloc(sizeof(struct md5_memory_entry)));
(*next_ptr)->digest = *digest;
ASSERT ((*next_ptr)->str = (char *) malloc(strlen(str)+1));
strcpy ((*next_ptr)->str, str);
(*next_ptr)->next = NULL;
}
static md5_digest
digest_section_name (const char * name)
{
const char * salt = getenv ("SHUFFLE_OBFUSCATION_SALT");
struct md5_ctx ctx;
md5_digest result;
if (salt == NULL)
{
static bfd_boolean warning_reported = FALSE;
salt = "";
if (!warning_reported)
{
einfo (_("Forgot to set environment variable SHUFFLE_OBFUSCATION_SALT?\n"));
warning_reported = TRUE;
}
}
md5_init_ctx (&ctx);
md5_process_bytes ((const void *) salt, strlen (salt), &ctx);
md5_process_bytes ((const void *) name, strlen (name), &ctx);
(void) md5_finish_ctx (&ctx, (void *) &result);
return result;
}
/* Compare sections ASEC and BSEC according to SORT. */
static int
......@@ -461,11 +528,38 @@ sort_by_name:
ret = (bfd_section_alignment (bsec->owner, bsec)
- bfd_section_alignment (asec->owner, asec));
break;
case SHUFFLE_OBFUSCATION:
{
md5_digest digest_a, digest_b;
digest_a = digest_section_name (bfd_get_section_name (asec->owner, asec));
digest_b = digest_section_name (bfd_get_section_name (bsec->owner, bsec));
check_md5_memory(bfd_get_section_name (asec->owner, asec), &digest_a);
check_md5_memory(bfd_get_section_name (bsec->owner, bsec), &digest_b);
ret = memcmp ((const void *) &digest_a, (const void*) &digest_b, 128/8);
}
break;
}
return ret;
}
#if 0
/* Shuffle instead of sorting. */
static lang_section_bst_type **
wild_shuffle_fast (lang_wild_statement_type *wild,
struct wildcard_list *sec,
lang_input_statement_type *file ATTRIBUTE_UNUSED,
asection *section)
{
// TODO!
(void) wild;
(void) sec;
(void) section;
return NULL;
}
#endif
/* Build a Binary Search Tree to sort sections, unlike insertion sort
used in wild_sort(). BST is considerably faster if the number of
of sections are large. */
......@@ -524,6 +618,7 @@ output_section_callback_fast (lang_wild_statement_type *ptr,
node->right = 0;
node->section = section;
/* tree = (sec->spec.sorted == SHUFFLE_OBFUSCATION ? wild_shuffle_fast : wild_sort_fast) (ptr, sec, file, section); */
tree = wild_sort_fast (ptr, sec, file, section);
if (tree != NULL)
*tree = node;
......@@ -2461,6 +2556,23 @@ lang_add_section (lang_statement_list_type *ptr,
new_section->section = section;
}
#if 0
/* Shuffle instead of sorting. */
static lang_statement_union_type *
wild_shuffle (lang_wild_statement_type *wild,
struct wildcard_list *sec,
lang_input_statement_type *file,
asection *section) {
// TODO!
(void) wild;
(void) sec;
(void) file;
(void) section;
return NULL;
}
#endif
/* Handle wildcard sorting. This returns the lang_input_section which
should follow the one we are going to create for SECTION and FILE,
based on the sorting requirements of WILD. It returns NULL if the
......@@ -2577,6 +2689,7 @@ output_section_callback (lang_wild_statement_type *ptr,
if (unique_section_p (section, os))
return;
/* before = (sec->spec.sorted == SHUFFLE_OBFUSCATION ? wild_shuffle : wild_sort) (ptr, sec, file, section); */
before = wild_sort (ptr, sec, file, section);
/* Here BEFORE points to the lang_input_section which
......@@ -3528,6 +3641,7 @@ update_wild_statements (lang_statement_union_type *s)
case by_name:
case by_alignment:
case SHUFFLE_OBFUSCATION:
for (; s != NULL; s = s->header.next)
{
switch (s->header.type)
......@@ -3552,6 +3666,9 @@ update_wild_statements (lang_statement_union_type *s)
if (sort_section == by_name)
sec->spec.sorted = by_alignment_name;
break;
case SHUFFLE_OBFUSCATION:
FAIL (); /* TODO! */
break;
default:
break;
}
......
......@@ -426,7 +426,7 @@ static const struct ld_option ld_options[] =
{ {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
'\0', NULL, NULL, NO_HELP },
{ {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
'\0', N_("name|alignment"),
'\0', N_("name|alignment|shuffle_obfuscation"),
N_("Sort sections by name or maximum alignment"), TWO_DASHES },
{ {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
'\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
......@@ -1192,6 +1192,8 @@ parse_args (unsigned argc, char **argv)
sort_section = by_name;
else if (strcmp (optarg, N_("alignment")) == 0)
sort_section = by_alignment;
else if (strcmp (optarg, N_("shuffle_obfuscation")) == 0)
sort_section = SHUFFLE_OBFUSCATION;
else
einfo (_("%P%F: invalid section sorting option: %s\n"),
optarg);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment