bp2build; Update handling of linker flags

Test: build/bazel/ci/bp2build.sh
Bug: 197920036
Change-Id: I6e3100574fa0e40bcd8cf0e6af0efd3310aa41bf
diff --git a/cc/bp2build.go b/cc/bp2build.go
index ebba9d1..f3c999d 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -373,15 +373,7 @@
 	stripKeepSymbolsList          bazel.StringListAttribute
 	stripAll                      bazel.BoolAttribute
 	stripNone                     bazel.BoolAttribute
-}
-
-// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
-func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
-	flags := linkerProperties.Ldflags
-	if !BoolDefault(linkerProperties.Pack_relocations, true) {
-		flags = append(flags, "-Wl,--pack-dyn-relocs=none")
-	}
-	return flags
+	features                      bazel.StringListAttribute
 }
 
 // bp2BuildParseLinkerProps parses the linker properties of a module, including
@@ -408,6 +400,8 @@
 	var stripAll bazel.BoolAttribute
 	var stripNone bazel.BoolAttribute
 
+	var features bazel.StringListAttribute
+
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
 		for config, props := range configToProps {
 			if stripProperties, ok := props.(*StripProperties); ok {
@@ -426,6 +420,7 @@
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
 		for config, props := range configToProps {
 			if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
+				var axisFeatures []string
 
 				// Excludes to parallel Soong:
 				// https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
@@ -457,7 +452,15 @@
 				headerDeps.SetSelectValue(axis, config, hDeps.export)
 				implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation)
 
-				linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
+				linkopts.SetSelectValue(axis, config, baseLinkerProps.Ldflags)
+				if !BoolDefault(baseLinkerProps.Pack_relocations, packRelocationsDefault) {
+					axisFeatures = append(axisFeatures, "disable_pack_relocations")
+				}
+
+				if Bool(baseLinkerProps.Allow_undefined_symbols) {
+					axisFeatures = append(axisFeatures, "-no_undefined_symbols")
+				}
+
 				if baseLinkerProps.Version_script != nil {
 					versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
 				}
@@ -471,6 +474,10 @@
 						disallowedArchVariantCrt = true
 					}
 				}
+
+				if axisFeatures != nil {
+					features.SetSelectValue(axis, config, axisFeatures)
+				}
 			}
 		}
 	}
@@ -559,6 +566,8 @@
 		stripKeepSymbolsList:          stripKeepSymbolsList,
 		stripAll:                      stripAll,
 		stripNone:                     stripNone,
+
+		features: features,
 	}
 }
 
diff --git a/cc/library.go b/cc/library.go
index 58e0e21..0cffd56 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -259,6 +259,8 @@
 	Static staticOrSharedAttributes
 
 	Strip stripAttributes
+
+	Features bazel.StringListAttribute
 }
 
 type stripAttributes struct {
@@ -340,6 +342,8 @@
 		Shared: sharedAttrs,
 
 		Static: staticAttrs,
+
+		Features: linkerAttrs.features,
 	}
 
 	props := bazel.BazelTargetModuleProperties{
@@ -2407,6 +2411,8 @@
 			Cppflags:   compilerAttrs.cppFlags,
 			Conlyflags: compilerAttrs.conlyFlags,
 			Asflags:    asFlags,
+
+			Features: linkerAttrs.features,
 		}
 	} else {
 		attrs = &bazelCcLibrarySharedAttributes{
@@ -2435,6 +2441,8 @@
 				All:                          linkerAttrs.stripAll,
 				None:                         linkerAttrs.stripNone,
 			},
+
+			Features: linkerAttrs.features,
 		}
 	}
 
@@ -2464,6 +2472,8 @@
 	Cppflags   bazel.StringListAttribute
 	Conlyflags bazel.StringListAttribute
 	Asflags    bazel.StringListAttribute
+
+	Features bazel.StringListAttribute
 }
 
 func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
@@ -2492,6 +2502,8 @@
 	Cppflags   bazel.StringListAttribute
 	Conlyflags bazel.StringListAttribute
 	Asflags    bazel.StringListAttribute
+
+	Features bazel.StringListAttribute
 }
 
 func CcLibrarySharedBp2Build(ctx android.TopDownMutatorContext) {
diff --git a/cc/linker.go b/cc/linker.go
index 20e377c..aaaca7a 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -27,6 +27,10 @@
 // This file contains the basic functionality for linking against static libraries and shared
 // libraries.  Final linking into libraries or executables is handled in library.go, binary.go, etc.
 
+const (
+	packRelocationsDefault = true
+)
+
 type BaseLinkerProperties struct {
 	// list of modules whose object files should be linked into this module
 	// in their entirety.  For static library modules, all of the .o files from the intermediate
@@ -471,7 +475,7 @@
 
 	if linker.useClangLld(ctx) {
 		flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod))
-		if !BoolDefault(linker.Properties.Pack_relocations, true) {
+		if !BoolDefault(linker.Properties.Pack_relocations, packRelocationsDefault) {
 			flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none")
 		} else if ctx.Device() {
 			// SHT_RELR relocations are only supported at API level >= 30.