Linux内核具有一个gcc插件,该插件在PLUGIN_FINISH_TYPE事件发生钩子时会重排某些结构的成员。
它在生成的二进制文件上很有效(成员的顺序是随机的),但对侏儒调试信息没有影响。实际上,尽管结构成员以二进制形式进行了很好的混洗,但是这些结构的调试信息仍按源顺序保留。
插件如何要求gcc重做刚刚改组的结构的调试信息?
基本上,插件的工作方式如下:
// put all fields of a struct in a tab newtree[]
// shuffle this array
// redo the tree chain
for (i = 0; i < num_fields - 1; i++)
TREE_CHAIN(newtree[i]) = newtree[i+1];
TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
// create a new FIELD_DECL
list = make_node(FIELD_DECL);
TREE_CHAIN(list) = newtree[0];
// and replace type fields of all variant of our struct (->type)
main_variant = TYPE_MAIN_VARIANT(type);
for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant))
TYPE_FIELDS(variant) = list;
// finally, force a relayout of the main variant
TYPE_SIZE(main_variant) = NULL_TREE;
layout_type(main_variant);
// Call to rebuild the debug informations ?